#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
#include <vector>
#include <string>
#include <unistd.h>
#include <ctime>
using namespace std;
using namespace ThreadModule;
using ringqueue_t = RingQueue<Task>;

// 消费者线程执行方法
void Consumer(ringqueue_t &rq, string name)
{
    // 消费者获取数据
    int data;
    while (true)
    {
        // 消费者消费数据
        // rq.Pop(&data);
        Task t;
        rq.Pop(&t);
        // cout << "消费者线程名称：" << name << "---消费者消费的数据:" << data << endl;
        cout << "消费者线程名称：" << name << endl;
        // 处理任务
        t();
        sleep(1);
    }
}
// int cnt = 0;
// 生产者线程执行方法
void Productor(ringqueue_t &rq, string name)
{
    // 生产者生产数据
    int cnt = 0;
    while (true)
    {
        // 生产数据
        // 生产任务
        cout << "生产者线程名称：" << name << "---生产者生产任务" << endl;
        rq.Enqueue(Download);
        // cout << "生产者线程名称：" << name << "---生产者生产的数据为:" << cnt << endl;
        // cnt++;
        sleep(1);
    }
}
// 公共方法
void InitComm(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq, func_t<ringqueue_t> func, string role)
{
    for (int i = 0; i < num; i++)
    {
        sleep(1);
        // 为每个消费者线程构建名称
        string name = role + "->thread-" + to_string(i + 1);
        // 管理每个消费者线程
        threads->push_back(Thread<ringqueue_t>(func, rq, name));
        // 启动每个消费者线程
        //(*threads)[threads->size() - 1].Start();
        // threads->back().Start();
    }
}
// 创建-管理消费者线程
void InitConsumer(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Consumer, "consumer");
}
// 创建-管理生产者线程
void InitProductor(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
    InitComm(threads, num, rq, Productor, "productor");
}
// 等待回收所有线程
void WaitALLThread(vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}
// 启动所有线程
void StartAll(vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Start();
    }
}
int main()
{
    // 阻塞队列
    ringqueue_t *rq = new ringqueue_t(5);
    // 管理生产者和消费者线程的数据结构
    vector<Thread<ringqueue_t>> threads;
    // 构建指定数量的消费者线程
    InitConsumer(&threads, 3, *rq);
    // 构建指定数量的生产者线程
    InitProductor(&threads, 4, *rq);
    // 启动所有线程(生产者---消费者)
    StartAll(threads);
    // 等待回收所有线程
    WaitALLThread(threads);
    return 0;
}